﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DTS
{
    class PortfelController
    {
        List<Walor> walory;
        Double gotowka;
        Double prowizja;

        public PortfelController()
        {
            walory = new List<Walor>();
            gotowka = 1000; // test -----> to set = 0
            prowizja = 0.0039;
        }
        public Double getGotowka() { return gotowka; }
        public List<Walor> getWalory() { return walory; }
        public Walor getWalor(String sym)
        {
            return walory.Find(w => sym.Equals(w.getSymbol()));
        }
        public Double getProwizja() { return prowizja; }
        public void setGotowka(Double val) { gotowka = val; gotowka = Math.Round(gotowka, 2); }
        public void setWalory(List<Walor> w) { walory = w; }
        public void setProwizja(Double val) { prowizja = val; }
        public void addGotowka(Double val) { gotowka += val; gotowka = Math.Round(gotowka, 2); }
        public bool subGotowka(Double val)
        {
            if (gotowka - val < 0) return false;
            gotowka -= val;
            gotowka = Math.Round(gotowka, 2);
            return true;
        }
        public List<Transakcja> transakcja(String symbol, int ilosc,bool isShort,Double cena,ref Walor walor_ret, DateTime data, String kto)
        {
            List<Transakcja> toRet = new List<Transakcja>();
            Walor w = walory.Find(wal => wal.getSymbol().Contains(symbol));
            if (w == null) // warunek 1 - nie bylo posiadane w portfelu wczesniej.
            {
                if (gotowka >= (1 + prowizja) * ilosc * cena)
                {
                    gotowka = gotowka - (1 + prowizja) * ilosc * cena;
                    gotowka = Math.Round(gotowka, 2);
                    w = new Walor(symbol, isShort, ilosc, cena,kto);
                    walory.Add(w);
                    walor_ret = w;
                    if (isShort)
                        toRet.Add(new Transakcja(symbol,ilosc,RodzajTransakcji.krotkie_kupno,cena,prowizja,0,data,kto));
                    else
                        toRet.Add(new Transakcja(symbol, ilosc, RodzajTransakcji.kupno, cena, prowizja, 0, data,kto));
                    return toRet;
                }
                else return null;
            }
            else
            {
                if (w.getIsShort() == isShort) // warunek 2 - bylo w portfelu uzupelniamy pozycje
                {
                    if (gotowka >= (1 + prowizja) * ilosc * cena)
                    {
                        gotowka = gotowka - (1 + prowizja) * ilosc * cena;
                        gotowka = Math.Round(gotowka, 2);
                        Double newAvg = w.getLiczba() * w.getAvgBuy() + ilosc*cena;
                        w.setLiczba(w.getLiczba() + ilosc);
                        newAvg = newAvg / w.getLiczba();
                        w.setAvgBuy(newAvg);
                        // jesli sie ref w nie zmienia w liscie to trzeba wywalic i dodac jeszcze raz
                        walor_ret = w;
                        if (isShort)
                            toRet.Add(new Transakcja(symbol, ilosc, RodzajTransakcji.krotkie_kupno, cena, prowizja, 0, data,kto));
                        else
                            toRet.Add(new Transakcja(symbol, ilosc, RodzajTransakcji.kupno, cena, prowizja, 0, data, kto));
                        return toRet;
                    }
                    else return null;

                }
                else // warunek 3 - bylo w portfelu - zamykamy pozycje (+ ewentualnie otwieramy przeciwną)
                {
                    if (w.getLiczba() >= ilosc) // zamykamy czesc lub calosc pozycji bez otwierania przeciwnej
                    {
                        Double zysk;
                        if (w.getIsShort())
                            zysk = w.getAvgBuy() * ilosc*(1-prowizja) - cena * ilosc*(1+prowizja);
                        else
                            zysk = cena * ilosc *(1 - prowizja) - w.getAvgBuy() * ilosc*(1 + prowizja);
                        gotowka = gotowka + zysk + w.getAvgBuy() *ilosc*(1+prowizja);
                        gotowka = Math.Round(gotowka, 2);
                        w.setLiczba(w.getLiczba() - ilosc);
                        walor_ret = w;
                        if (w.getLiczba() == 0) walory.Remove(w);
                        if (isShort)
                            toRet.Add(new Transakcja(symbol, ilosc, RodzajTransakcji.sprzedaz, cena, prowizja, zysk, data, kto));
                        else
                            toRet.Add(new Transakcja(symbol, ilosc, RodzajTransakcji.krotka_sprzedaz, cena, prowizja, zysk, data, kto));
                        return toRet;
                    }
                    else // zamykamy cala pozycje i otwieramy przeciwna
                    {
                        Double zysk;
                        if (w.getIsShort())
                            zysk = w.getAvgBuy() * w.getLiczba() * (1 - prowizja) - cena * w.getLiczba() * (1 + prowizja);
                        else
                            zysk = cena * w.getLiczba() * (1 - prowizja) - w.getAvgBuy() * w.getLiczba() * (1 + prowizja);
                        int nowaIlosc = ilosc - w.getLiczba();
                        if (gotowka + zysk + w.getAvgBuy() * ilosc * (1 + prowizja) >= (1 + prowizja) * nowaIlosc * cena)
                        {
                            gotowka = gotowka + zysk + w.getAvgBuy() * w.getLiczba() * (1 + prowizja) - (1 + prowizja) * nowaIlosc * cena;
                            gotowka = Math.Round(gotowka, 2);
                            w.setLiczba(nowaIlosc);
                            w.setAvgBuy(cena);
                            w.setIsShort(!w.getIsShort());
                            walor_ret = w;
                            if (isShort)
                            {
                                toRet.Add(new Transakcja(symbol, w.getLiczba(), RodzajTransakcji.sprzedaz, cena, prowizja, zysk, data, kto));
                                toRet.Add(new Transakcja(symbol, ilosc - w.getLiczba(), RodzajTransakcji.krotkie_kupno, cena, prowizja, 0, data, kto));
                            }
                            else
                            {
                                toRet.Add(new Transakcja(symbol, w.getLiczba(), RodzajTransakcji.krotka_sprzedaz, cena, prowizja, zysk, data, kto));
                                toRet.Add(new Transakcja(symbol, ilosc - w.getLiczba(), RodzajTransakcji.kupno, cena, prowizja, 0, data, kto));
                            }
                            return toRet;
                        }
                        else return null;
                    }
                }

            }
        }
        override public string ToString()
        {
            String toRet = "Gotowka: " + gotowka.ToString();
            foreach (Walor tmp in walory)
                toRet += "\n" + tmp.ToString();
            return toRet;
        }
    }
}
